﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace ExpressionToWhere
{
    public static class ExpressionExtension
    {
        /// <summary>
        /// 将Expression表达式转换成where参数化查询条件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expression">表示查询条件的Expression表达式</param>
        /// <param name="addWherePrimarykey">是否在开头添加where关键字</param>
        /// <param name="searchNull">=、大于等于、小于等于、!=是否处理null参数值（true时：Name = null 转换成Name is null，false时：Name = null直接忽略不生成查询条件）</param>
        /// <param name="dbType">数据库类型（SqlServer、MySql、Oracle）</param>
        /// <returns></returns>
        public static (string, Dictionary<string, object>) ToWhereParametric<T>(this Expression<Func<T, bool>> expression, bool searchNull = true, bool addWherePrimarykey = true, string dbType="SqlServer") where T : class
        {
            ExpressionProcesser.Parametric = true;
            ExpressionProcesser processer = new ExpressionProcesser();
            processer.HandleExpression(expression.Body, searchNull, dbType);
            (string sql, Dictionary<string, object> dict) = processer.GetResult();
            if (addWherePrimarykey && !string.IsNullOrEmpty(sql))
            {
                sql = "where " + sql;
            }
            return (sql, dict);
        }

        /// <summary>
        /// 将Expression表达式转换成where非参数化查询条件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="expression">表示查询条件的Expression表达式</param>
        /// <param name="addWherePrimarykey">是否在开头添加where关键字</param>
        /// <param name="searchNull">=、大于等于、小于等于、!=是否处理null参数值（true时：Name = null 转换成Name is null，false时：Name = null直接忽略不生成查询条件）</param>
        /// <param name="dbType">数据库类型（SqlServer、MySql、Oracle）</param>
        /// <returns></returns>
        public static string ToWhereNonParametric<T>(this Expression<Func<T, bool>> expression, bool searchNull = true, bool addWherePrimarykey = true, string dbType = "SqlServer") where T : class
        {
            ExpressionProcesser.Parametric = false;
            ExpressionProcesser processer = new ExpressionProcesser();
            processer.HandleExpression(expression.Body, searchNull, dbType);
            (string sql, Dictionary<string, object> dict) = processer.GetResult();
            if (addWherePrimarykey && !string.IsNullOrEmpty(sql))
            {
                sql = "where " + sql;
            }
            return sql;
        }
    }
}
